웹개발 및 최신 테크 소식을 전하는 블로그, 웹이즈프리

HOME > js

[자바스크립트] 이벤트 버블링 제거방법 stopPropagation()

Last Modified : 2021-07-13 / Created : 2016-06-15
45,295
View Count

자바스크립트를 사용하여 이벤트를 구현할 때 이벤트 캡처링과 이벤트 버블링이 등장합니다. 아래에서는 이벤트 버블링(Event Bubbling)이 무엇이고 관련된 이슈가 왜 발생하는지 ~ 또 어떻게 해결하는지 알아보겠습니다. 먼저 이벤트 버블링이 무엇인지 알아봅니다.

이벤트 버블링이란이벤트 버블링은 선택한 엘리먼트가 부모 요소를 가지는 경우에 발생한다. 모든 요소들은 body부터 하위 자식 요소들까지 계층 구조를 가지고 있습니다. 예를들어 만약 부모 요소 안에 있는 어떤 엘리먼트를 클릭한다고 생각해봅니다. 이때 해당 엘리먼트를 포함하는 부모 요소를 클릭하지 않을 수 있을까요? 내부에 존재하기 때문에 당연히 어렵겠죠. 실제로는 아래와 같이 dep1, dep2를 지나야 dep3를 클릭할 수 있습니다.

그림) html 코드는 이처럼 계층형 구조를 가지므로 부모요소 간섭의 이벤트 버블링이 발생 가능함
여기서 이벤트 버블링은 해당 클릭 이벤트처럼 이벤트가 전파가 자식에서 부모로 이동하는 것을 의미합니다. 가장 최상위 부모로는 html, body가 존재하겠죠 ~ 이처럼 이벤트 전파가 발생하므로 dep1, dep2, dep3에 콜백함수가 각각 존재한다면 dep3가 가장 먼저 실행되고 뒤 이어서 dep2, dep1이 실행됩니다.



! 만약 이벤트 전파가 되지 않도록 하려면?


이 경우 사용 가능한 방법이 바로 stopPropagation()을 사용하는 방법입니다. propagation은 사전적 의미로 번식이란 의미를 가지며 부모로 부터 생산된 어떤 것을 의미하죠~ 즉 stopPropagation() 함수를 사용하면 부모에 의한 이벤트 버블링을 stop하여 간단하게 막을 수 있게 됩니다. 매우 간단하죠?



! stopPropagation() 함수 예제보기


아래 예제는 이벤트 전파가 발생할 수 있는 이벤트 버블링을 구현하고 클릭시 버블링이 나타나지 않도록 코드를 작성하였습니다.
<style type="text/css">
.dep1 {
   width: 200px;
   height: 200px;
   display: block;
   background-color: #dcdcdc;
}
.dep2 {
   width: 100px;
   height: 100px;
   display: block;
   margin: 3px auto;
   background-color: #ececec;
}
button {
   display: block;
   margin: 0 auto;
}
</style>

<div class="dep1" onclick="doDep1(event);">
   dep1
   <div class="dep2" onclick="doDep2(event);">
      dep2<br /><br />
      <button onclick="doDep3(event);">dep3</button>
   </div>
</div> 

여기까지는 html 그리고 css 코드입니다. 위 코드를 실행하면 각각의 상위 요소와 하위 요소 세가지가 존재하며 모든 요소들은 클릭 이벤트를 가지고 있습니다. 만약 사용자가 가장 하위의 요소를 클릭할 경우 이벤트 전파를 억제하여 부모가 가진 이벤트 콜백은 실행되지 않도록 하는 코드를 작성하는 것이 목적입니다.

이를 구현하기 위하여 아래와 같이 스크립트를 작성합니다.
var doDep1 = function(event) {
   alert('Clicked dep1');
}
var doDep2 = function(event) {
   alert('Clicked dep2');
}
var doDep3 = function(event) {
   event.stopPropagation();
   alert('Clicked dep3');
}

위 스크립트는 각각의 요소들이 클릭시 현재 요소가 클릭되었음을 브라우저의 Alert을 사용하여 출력하는 소스 예제입니다. 여기서 dep3의 클래스를 가진 요소만 event.stopPropagation() 코드를 추가하였습니다. 그래서 dep3 요소를 클릭하면 이벤트 버블링이 발생하지 않고(부모 요소들의 함수는 실행되지 않고) 오직 doDep3 함수만 실행되게 됩니다.

실제로 클릭하면 기대한 효과가 나타나게 됩니다. 그렇다면 만약 다른 요소 dep2를 클릭하면 어떻게 될까요? dep2는 stopPropagation이 없기 때문에 dep1 요소의 콜백함수도 같이 출력될 것이라 예상할 수 있습니다. 이는 아래에서 직접 클릭해보시기 바랍니다.




dep1



dep2














이벤트 버블링을 생각하지 못하고 코드를 작성하면 생각하지 못한 이벤트가 발생하거나 예상한 순서와는 다르게 발생할 수 있습니다. 꼭 알아두시기 바랍니다.

Previous

제이쿼리ui dialog 모달 사용방법

Previous

ajax 타이머로 일정시간 단위로만 요청보내기